package com.wcity.manage.common.interceptor;

import com.wcity.manage.common.config.AppConfig;
import com.wcity.manage.common.context.Constants;
import com.wcity.manage.common.context.SessionKey;
import com.wcity.manage.common.enums.Code;
import com.wcity.manage.common.exception.CustomException;
import com.wcity.manage.common.utils.DwzUtil;
import com.wcity.manage.common.utils.RespUtil;
import com.wcity.manage.common.utils.StringUtil;
import com.wcity.manage.dao.model.User;
import com.wcity.manage.service.AuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 鉴权拦截器
 * 
 * @author dy
 * @modify jn
 *
 */
public class AccessInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler ) throws Exception {

		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		response.addHeader( "Access-Control-Allow-Origin", "*" );
		response.addHeader( "Access-Control-Allow-Credentials", "true" );
		response.setHeader( "Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS" );
		response.setHeader( "Access-Control-Allow-Headers", "x-requested-with,content-type,openid,appid" );
		if ("OPTIONS".equalsIgnoreCase(request.getMethod())){
			return false;
		}

		String act = getAct( request.getRequestURI(), request.getContextPath() );
		// log.debug( "Request Act ==> {}", act );

		// debug mode
		if ( AppConfig.getInstace().isDebug() ) return true;

		// 拦截器白名单
		for ( String skip : AppConfig.getInstace().getSkipUrl() ) {
			if ( skip.equals( act ) ) {
				// 接口验证
				if ( "/v1".equals( act ) ) {
					String token = request.getParameter("token");
					String registerId = request.getParameter("registerId");
					// token检查
					String errorMsg = authService.checkToken( token, registerId );

					if ( StringUtil.isBlank( errorMsg ) ) {
						return true;
					} else if ( Constants.TOKEN_EXPIRE_ERROR.equals( errorMsg ) ){
						// 在其他设备登陆
						throw new CustomException( errorMsg, Code.TOKEN_EXPIRE );
					} else {
						throw new CustomException( errorMsg, Code.ERROR );
					}
				}
				return true;
			}
		}

		// 获取用户
		User userInfo = (User)request.getSession().getAttribute( SessionKey.SESSION_USER_INFO );
		if ( userInfo == null ) {
			String json = DwzUtil.getRetAuthJson( Constants.DWZ.CODE_AUTH_TIMEOUT, "登录超时，请重新登录" );
			RespUtil.sendJson( response, json );
			return false;
		}

		// 鉴权
		String authStr = authService.checkAuth( userInfo, act );
		if ( StringUtil.isBlank(authStr) ) {
			return true;
		} else {
			String json = DwzUtil.getRetAuthJson( Constants.DWZ.CODE_AUTH_ERROR, authStr );
			RespUtil.sendJson( response, json );
			return false;
		}
	}
	
	@Override
	public void afterCompletion( 
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception e ) throws Exception {
		
	}

	@Override
	public void postHandle( 
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav ) throws Exception {
		
	}
	
	/**
	 * 获取请求act
	 * 
	 * @param requestURI
	 * @param contextPath
	 * @return
	 */
	private String getAct( String requestURI, String contextPath ) {
		
		String act = requestURI.substring( contextPath.length(), requestURI.length() );
		
		// 检查是否是多级目录访问
		String check = act.substring( act.indexOf( "/" ) + 1, act.length() );
		if ( check.contains( "/" ) ) {
			act = act.substring( 0,  check.indexOf( "/" ) + 1 );
		}
		return act;
	}

	@Resource private AuthService authService;

	private final static Logger log = LoggerFactory.getLogger( AccessInterceptor.class.getName() );

}
